import Vue from "vue";
import axios from "axios";
import { Notify } from "quasar";
import qs from "qs"; //qs 库，它提供了一些工具函数，用于序列化和反序列化 URL 查询字符串
import Router from "../router/index";
import { permissionService } from "../service";

// 将 axios 库添加到 Vue 的原型中，使得在 Vue 组件中可以通过 this.$axios 来访问 axios 对象
Vue.prototype.$axios = axios;

// We create our own axios instance and set a custom base URL.
// Note that if we wouldn't set any config here we do not need
// a named export, as we could just `import axios from 'axios'`
const axiosInstance = axios.create({
  baseURL: process.env.API,
});

// transformRequest 是 axios 中一个用于在发送请求之前对请求数据进行转换的配置项，
// 允许开发者修改请求数据的方式。
// 这个函数是一个数组，包含了多个函数，每个函数会按顺序对请求数据进行转换
axiosInstance.defaults.transformRequest = [
  function (data, headers) {
    // Do whatever you want to transform the data
    let contentType = headers["Content-Type"] || headers["content-type"];
    if (!contentType) {
      contentType = "application/json";
      headers["Content-Type"] = "application/json";
    }

    if (contentType.indexOf("multipart/form-data") >= 0) {
      return data;
    } else if (contentType.indexOf("application/x-www-form-urlencoded") >= 0) {
      return qs.stringify(data); //将数据转换为 URL 查询字符串形式
    }

    return JSON.stringify(data);
  },
];

// 注册了一个请求拦截器，该拦截器在每次请求被发送之前执行
axiosInstance.interceptors.request.use(
  //第一个参数是一个成功的回调函数，它会接收 config 对象，代表请求的配置
  function (config) {
    //在请求发送前检查用户是否有权限执行该请求
    if (config.permission && !permissionService.check(config.permission)) {
      throw {
        message: "403 forbidden", //权限检查不通过，请求被中止
      };
    }

    if (config.dataSource) {
      console.log("config.dataSource = " + config.dataSource);
      config.headers["dataSource"] = config.dataSource; //在请求头中添加额外的自定义信息
    }

    return config;
  },
  //第二个参数是一个失败的回调函数，用于处理请求错误。
  function (error) {
    // 将错误对象通过 Promise.reject(error) 返回，以便后续的错误处理能够捕获并处理这个错误
    return Promise.reject(error);
  }
);

function login() {
  setTimeout(() => {
    Router.push({
      path: "/login",
    });
  }, 1000);
}

//注册了一个响应拦截器，该拦截器在每次接收到响应后执行
axiosInstance.interceptors.response.use(
  //第一个参数是一个成功的回调函数，它接收 response 对象，代表从服务器返回的响应
  function (response) {
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return response;
  },
  //第二个参数是一个失败的回调函数，它接收 error 对象，代表发生的响应错误
  function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error

    if (error.response) {
      //服务器已经响应，但是响应状态码不在 2xx 的范围内
      if (error.response.status === 401) {
        //未授权
        Notify.create({
          message: error.response.data.message,
          type: "negative",
        });
        login();
      } else if (error.response.data && error.response.data.message) {
        Notify.create({
          message: error.response.data.message,
          type: "negative",
        });
      } else {
        Notify.create({
          message: error.response.statusText || error.response.status,
          type: "negative",
        });
      }
    } else if (error.message.indexOf("timeout") > -1) {
      //服务器超时未响应
      Notify.create({
        message: "Network timeout",
        type: "negative",
      });
    } else if (error.message) {
      //服务器未响应
      Notify.create({
        message: error.message,
        type: "negative",
      });
    } else {
      Notify.create({
        message: "http request error",
        type: "negative",
      });
    }

    return Promise.reject(error); //将错误对象传递给后续的错误处理
  }
);

// for use inside Vue files through this.$axios
Vue.prototype.$axios = axiosInstance;

// Here we define a named export
// that we can later use inside .js files:
export { axiosInstance };
